﻿2026-05-16T03:14:10.1272899Z ##[group]Run pnpm verify:phase-4
2026-05-16T03:14:10.1273827Z [36;1mpnpm verify:phase-4[0m
2026-05-16T03:14:10.1309996Z shell: /usr/bin/bash -e {0}
2026-05-16T03:14:10.1310268Z env:
2026-05-16T03:14:10.1310536Z   PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
2026-05-16T03:14:10.1310881Z   SKIP_PHASE_3_CARRYOVER: 1
2026-05-16T03:14:10.1311121Z   SKIP_TRACE_CHECK: 1
2026-05-16T03:14:10.1311343Z ##[endgroup]
2026-05-16T03:14:10.4339981Z 
2026-05-16T03:14:10.4340987Z > rebno@0.0.0 verify:phase-4 /home/runner/work/rebno/rebno
2026-05-16T03:14:10.4342195Z > node scripts/verify-phase-4.mjs
2026-05-16T03:14:10.4342778Z 
2026-05-16T03:14:10.4664788Z 
2026-05-16T03:14:10.4665938Z === Workspace: typecheck ===
2026-05-16T03:14:10.4666714Z >>> pnpm -r typecheck
2026-05-16T03:14:10.7637112Z Scope: 5 of 6 workspace projects
2026-05-16T03:14:10.7691196Z packages/db typecheck$ tsc --noEmit
2026-05-16T03:14:10.7699605Z packages/game-logic typecheck$ tsc --noEmit
2026-05-16T03:14:13.3844665Z packages/game-logic typecheck: Done
2026-05-16T03:14:13.3890676Z packages/protocol typecheck$ tsc --noEmit
2026-05-16T03:14:15.1778637Z packages/db typecheck: Done
2026-05-16T03:14:16.6645510Z packages/protocol typecheck: Done
2026-05-16T03:14:16.6651416Z apps/client typecheck$ tsc --noEmit
2026-05-16T03:14:16.6655008Z apps/server typecheck$ tsc --noEmit
2026-05-16T03:14:28.7834254Z apps/client typecheck: Done
2026-05-16T03:14:29.0577588Z apps/server typecheck: Done
2026-05-16T03:14:29.0687437Z 
2026-05-16T03:14:29.0688216Z === Lint: protocol-sync ===
2026-05-16T03:14:29.0689031Z >>> pnpm lint:protocol-sync
2026-05-16T03:14:29.3714083Z 
2026-05-16T03:14:29.3715312Z > rebno@0.0.0 lint:protocol-sync /home/runner/work/rebno/rebno
2026-05-16T03:14:29.3716625Z > node tools/scripts/lint-protocol-sync.mjs
2026-05-16T03:14:29.3717236Z 
2026-05-16T03:14:29.4036443Z lint-protocol-sync: OK
2026-05-16T03:14:29.4168161Z 
2026-05-16T03:14:29.4168982Z === Lint: game-logic-purity ===
2026-05-16T03:14:29.4169832Z >>> pnpm lint:game-logic-purity
2026-05-16T03:14:29.7083783Z 
2026-05-16T03:14:29.7085022Z > rebno@0.0.0 lint:game-logic-purity /home/runner/work/rebno/rebno
2026-05-16T03:14:29.7086090Z > node tools/scripts/lint-game-logic-purity.mjs
2026-05-16T03:14:29.7086718Z 
2026-05-16T03:14:29.7425422Z lint-game-logic-purity: OK (8 file(s) clean)
2026-05-16T03:14:29.7559739Z 
2026-05-16T03:14:29.7560551Z === Lint: better-auth-schema-sync ===
2026-05-16T03:14:29.7561375Z >>> pnpm lint:better-auth-schema-sync
2026-05-16T03:14:30.0466650Z 
2026-05-16T03:14:30.0467834Z > rebno@0.0.0 lint:better-auth-schema-sync /home/runner/work/rebno/rebno
2026-05-16T03:14:30.0469022Z > node tools/scripts/lint-better-auth-schema-sync.mjs
2026-05-16T03:14:30.0469599Z 
2026-05-16T03:14:31.6563768Z lint-better-auth-schema-sync: OK
2026-05-16T03:14:31.6699250Z 
2026-05-16T03:14:31.6699901Z === Lint: rate-limit-budgets ===
2026-05-16T03:14:31.6700680Z >>> pnpm lint:rate-limit-budgets
2026-05-16T03:14:31.9640803Z 
2026-05-16T03:14:31.9642029Z > rebno@0.0.0 lint:rate-limit-budgets /home/runner/work/rebno/rebno
2026-05-16T03:14:31.9643428Z > node tools/scripts/lint-rate-limit-budgets.mjs
2026-05-16T03:14:31.9644007Z 
2026-05-16T03:14:31.9980705Z lint-rate-limit-budgets: OK (5 D-22 budgets locked)
2026-05-16T03:14:32.0117630Z 
2026-05-16T03:14:32.0118421Z === Lint: no-clipboard-rce ===
2026-05-16T03:14:32.0119198Z >>> pnpm lint:no-clipboard-rce
2026-05-16T03:14:32.3016580Z 
2026-05-16T03:14:32.3018044Z > rebno@0.0.0 lint:no-clipboard-rce /home/runner/work/rebno/rebno
2026-05-16T03:14:32.3019370Z > node tools/scripts/lint-no-clipboard-rce.mjs
2026-05-16T03:14:32.3020009Z 
2026-05-16T03:14:32.3392808Z lint-no-clipboard-rce: OK (22 file(s) clean)
2026-05-16T03:14:32.3525221Z 
2026-05-16T03:14:32.3526010Z === Lint: room-layout ===
2026-05-16T03:14:32.3526915Z >>> pnpm lint:room-layout
2026-05-16T03:14:32.6441590Z 
2026-05-16T03:14:32.6442759Z > rebno@0.0.0 lint:room-layout /home/runner/work/rebno/rebno
2026-05-16T03:14:32.6444117Z > node tools/scripts/lint-room-layout.mjs
2026-05-16T03:14:32.6445776Z 
2026-05-16T03:14:32.6832931Z lint-room-layout: OK
2026-05-16T03:14:32.6966800Z 
2026-05-16T03:14:32.6967567Z === ADR 0004 lint ===
2026-05-16T03:14:32.6968291Z >>> pnpm lint:adr:0004
2026-05-16T03:14:32.9905841Z 
2026-05-16T03:14:32.9907048Z > rebno@0.0.0 lint:adr:0004 /home/runner/work/rebno/rebno
2026-05-16T03:14:32.9908536Z > node tools/asset-catalog/scripts/lint-adr.mjs docs/adr/0004-room-hot-reload.md --no-matrix
2026-05-16T03:14:32.9909380Z 
2026-05-16T03:14:33.0228993Z OK: ADR docs/adr/0004-room-hot-reload.md validated (no-matrix mode — Michael Nygard sections present)
2026-05-16T03:14:33.0354895Z 
2026-05-16T03:14:33.0359573Z === Drizzle: emit-check ===
2026-05-16T03:14:33.0360279Z >>> pnpm db:emit-check
2026-05-16T03:14:33.3276889Z 
2026-05-16T03:14:33.3278031Z > rebno@0.0.0 db:emit-check /home/runner/work/rebno/rebno
2026-05-16T03:14:33.3280923Z > pnpm -C packages/db exec drizzle-kit generate && node -e "require('fs').copyFileSync('packages/db/migrations/0001_baseline.sql','docs/extracted-server/0001_baseline.sql')" && git diff --exit-code packages/db/migrations/0001_baseline.sql docs/extracted-server/0001_baseline.sql
2026-05-16T03:14:33.3282970Z 
2026-05-16T03:14:33.7721217Z No config path provided, using default 'drizzle.config.ts'
2026-05-16T03:14:33.7722982Z Reading config file '/home/runner/work/rebno/rebno/packages/db/drizzle.config.ts'
2026-05-16T03:14:34.2049532Z 8 tables
2026-05-16T03:14:34.2050315Z accounts 8 columns 1 indexes 0 fks
2026-05-16T03:14:34.2051185Z audit_log 6 columns 0 indexes 2 fks
2026-05-16T03:14:34.2052037Z characters 9 columns 0 indexes 1 fks
2026-05-16T03:14:34.2052813Z inventory_items 4 columns 0 indexes 1 fks
2026-05-16T03:14:34.2053830Z legacy_credentials_staging 6 columns 0 indexes 0 fks
2026-05-16T03:14:34.2054728Z message_board_replies 5 columns 0 indexes 2 fks
2026-05-16T03:14:34.2055550Z message_board_topics 7 columns 0 indexes 1 fks
2026-05-16T03:14:34.2056291Z sessions 5 columns 0 indexes 1 fks
2026-05-16T03:14:34.2056744Z 
2026-05-16T03:14:34.2057666Z No schema changes, nothing to migrate 😴
2026-05-16T03:14:34.9210902Z 
2026-05-16T03:14:34.9211811Z === Drizzle: schema-sync ===
2026-05-16T03:14:34.9212621Z >>> pnpm lint:schema-sync
2026-05-16T03:14:35.2069928Z 
2026-05-16T03:14:35.2071115Z > rebno@0.0.0 lint:schema-sync /home/runner/work/rebno/rebno
2026-05-16T03:14:35.2074750Z > node -e "const a=require('fs').readFileSync('packages/db/migrations/0001_baseline.sql');const b=require('fs').readFileSync('docs/extracted-server/0001_baseline.sql');if(Buffer.compare(a,b)!==0){console.error('docs/extracted-server/0001_baseline.sql out of sync with packages/db/migrations/0001_baseline.sql');process.exit(1)}console.log('OK')"
2026-05-16T03:14:35.2077234Z 
2026-05-16T03:14:35.2348353Z OK
2026-05-16T03:14:35.2476784Z 
2026-05-16T03:14:35.2477393Z === Drizzle: source-comments ===
2026-05-16T03:14:35.2478166Z >>> pnpm lint:source-comments
2026-05-16T03:14:35.5556502Z 
2026-05-16T03:14:35.5557485Z > rebno@0.0.0 lint:source-comments /home/runner/work/rebno/rebno
2026-05-16T03:14:35.5558561Z > pnpm -C packages/db run lint:source-comments
2026-05-16T03:14:35.5561785Z 
2026-05-16T03:14:35.8452086Z 
2026-05-16T03:14:35.8453678Z > @rebno/db@0.1.0 lint:source-comments /home/runner/work/rebno/rebno/packages/db
2026-05-16T03:14:35.8454929Z > node scripts/check-source-comments.mjs
2026-05-16T03:14:35.8455690Z 
2026-05-16T03:14:35.8767835Z check-source-comments: OK (50 columns, all SOURCE-cited)
2026-05-16T03:14:35.8999485Z 
2026-05-16T03:14:35.9000133Z === Workspace: test ===
2026-05-16T03:14:35.9000817Z >>> pnpm -r test
2026-05-16T03:14:36.1916616Z Scope: 5 of 6 workspace projects
2026-05-16T03:14:36.1967425Z packages/db test$ vitest run
2026-05-16T03:14:36.1976077Z packages/game-logic test$ vitest run
2026-05-16T03:14:36.6762224Z packages/game-logic test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/game-logic[39m
2026-05-16T03:14:36.6794639Z packages/db test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/db[39m
2026-05-16T03:14:37.1021487Z packages/game-logic test:  [32m✓[39m test/step-bno-fidelity.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-16T03:14:37.3115451Z packages/game-logic test:  [32m✓[39m test/wall-slide.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T03:14:37.5322702Z packages/game-logic test:  [32m✓[39m test/golden.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T03:14:37.6558244Z packages/db test:  [32m✓[39m tests/promotion.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T03:14:37.7635592Z packages/game-logic test:  [32m✓[39m test/walkable-edge.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:14:37.9039462Z packages/db test:  [32m✓[39m tests/save-format-traceability.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T03:14:37.9976191Z packages/game-logic test:  [32m✓[39m test/movement-constants.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T03:14:38.2142958Z packages/game-logic test:  [32m✓[39m test/sprite-state-machine.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T03:14:38.4172299Z packages/game-logic test:  [32m✓[39m test/navi-mask-bbox.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T03:14:38.6465664Z packages/game-logic test:  [32m✓[39m test/platform-cycle.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 17[2mms[22m[39m
2026-05-16T03:14:38.6763946Z packages/db test:  [32m✓[39m tests/schema-shape.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T03:14:38.6905175Z packages/db test: [2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
2026-05-16T03:14:38.6906801Z packages/db test: [2m      Tests [22m [1m[32m22 passed[39m[22m[90m (22)[39m
2026-05-16T03:14:38.6917026Z packages/db test: [2m   Start at [22m 03:14:36
2026-05-16T03:14:38.6920755Z packages/db test: [2m   Duration [22m 1.99s[2m (transform 156ms, setup 0ms, import 1.38s, tests 30ms, environment 0ms)[22m
2026-05-16T03:14:38.7164466Z packages/db test: Done
2026-05-16T03:14:38.7178149Z packages/protocol test$ vitest run
2026-05-16T03:14:38.8815694Z packages/game-logic test:  [32m✓[39m test/accumulator.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-16T03:14:39.1165344Z packages/game-logic test:  [32m✓[39m test/run-speed.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:14:39.2392440Z packages/protocol test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/protocol[39m
2026-05-16T03:14:39.3390115Z packages/game-logic test:  [32m✓[39m test/rng.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T03:14:39.3484682Z packages/game-logic test: [2m Test Files [22m [1m[32m11 passed[39m[22m[90m (11)[39m
2026-05-16T03:14:39.3520163Z packages/game-logic test: [2m      Tests [22m [1m[32m55 passed[39m[22m[90m (55)[39m
2026-05-16T03:14:39.3521470Z packages/game-logic test: [2m   Start at [22m 03:14:36
2026-05-16T03:14:39.3523577Z packages/game-logic test: [2m   Duration [22m 2.66s[2m (transform 249ms, setup 0ms, import 439ms, tests 97ms, environment 2ms)[22m
2026-05-16T03:14:39.3936347Z packages/game-logic test: Done
2026-05-16T03:14:39.5754365Z packages/protocol test:  [32m✓[39m test/codec.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T03:14:39.7441468Z packages/protocol test:  [32m✓[39m test/intents.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T03:14:39.9105215Z packages/protocol test:  [32m✓[39m test/state.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T03:14:40.0613815Z packages/protocol test:  [32m✓[39m test/schema-shape.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:14:40.0664626Z packages/protocol test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-16T03:14:40.0666640Z packages/protocol test: [2m      Tests [22m [1m[32m36 passed[39m[22m[90m (36)[39m
2026-05-16T03:14:40.0685219Z packages/protocol test: [2m   Start at [22m 03:14:39
2026-05-16T03:14:40.0686806Z packages/protocol test: [2m   Duration [22m 815ms[2m (transform 110ms, setup 0ms, import 216ms, tests 35ms, environment 0ms)[22m
2026-05-16T03:14:40.0986466Z packages/protocol test: Done
2026-05-16T03:14:40.0992183Z apps/client test$ vitest run --exclude 'test/e2e/**'
2026-05-16T03:14:40.0995024Z apps/server test$ vitest run --exclude 'test/**/*.integ.test.ts'
2026-05-16T03:14:40.6296146Z apps/server test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/apps/server[39m
2026-05-16T03:14:40.6925573Z apps/client test: [1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/rebno/rebno/apps/client[39m
2026-05-16T03:14:41.7156343Z apps/server test:  [32m✓[39m test/persistence.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 51[2mms[22m[39m
2026-05-16T03:14:42.0019266Z apps/server test:  [32m✓[39m test/rate-limit.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T03:14:42.4719098Z apps/server test:  [32m✓[39m test/layout-derive.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 127[2mms[22m[39m
2026-05-16T03:14:42.6697467Z apps/client test: [90mstderr[2m | src/__test__/game-scene.test.ts[2m > [22m[2mscenes/GameScene[2m > [22m[2mtest 5: onRoomLayout calls verifyRoomLayout first; render skipped on false
2026-05-16T03:14:42.6718149Z apps/client test: [22m[39mroom_layout signature did not verify — rendering anyway (defense-in-depth; see 06.1-D40-SPIKE.md) mvp-lobby 000
2026-05-16T03:14:42.7216802Z apps/server test:  [32m✓[39m test/room-key.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T03:14:42.7500250Z apps/client test:  [32m✓[39m src/__test__/game-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 233[2mms[22m[39m
2026-05-16T03:14:43.0070854Z apps/server test: {"level":40,"time":1778901283002,"pid":3334,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T03:14:43.0183333Z apps/server test:  [32m✓[39m test/staging-invite.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 19[2mms[22m[39m
2026-05-16T03:14:43.0295483Z apps/server test: {"level":40,"time":1778901283008,"pid":3334,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T03:14:43.0324660Z apps/server test: {"level":40,"time":1778901283009,"pid":3334,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T03:14:43.9288105Z apps/server test: {"level":30,"time":1778901283923,"pid":3365,"hostname":"runnervmrw5os","password":"[Redacted]","session_token":"[Redacted]","msg":"login"}
2026-05-16T03:14:43.9309108Z apps/server test:  [32m✓[39m test/otel-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[33m 704[2mms[22m[39m
2026-05-16T03:14:43.9325264Z apps/server test:      [33m[2m✓[22m[39m does not throw when OTEL_EXPORTER_OTLP_ENDPOINT is unset [33m 561[2mms[22m[39m
2026-05-16T03:14:44.0758964Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.teleport-gate.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 120[2mms[22m[39m
2026-05-16T03:14:44.8186264Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 1: fresh DB — migrate creates accounts table and records migration row
2026-05-16T03:14:44.8235135Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-huqTqe/rebno.db
2026-05-16T03:14:44.8236650Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T03:14:44.8270543Z apps/server test: [run-migrations] OK
2026-05-16T03:14:44.8325820Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 2: pre-bootstrapped DB (Assumption A7) — reconcile seeds row before migrate runs
2026-05-16T03:14:44.8344981Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-JclOU4/rebno.db
2026-05-16T03:14:44.8349943Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T03:14:44.8364240Z apps/server test: [run-migrations] reconciled __drizzle_migrations for pre-bootstrap DB (Assumption A7) — seeded 0001_baseline
2026-05-16T03:14:44.8368065Z apps/server test: [run-migrations] OK
2026-05-16T03:14:44.8421276Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T03:14:44.8442715Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-9F3xBI/rebno.db
2026-05-16T03:14:44.8445548Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T03:14:44.8447669Z apps/server test: [run-migrations] OK
2026-05-16T03:14:44.8480925Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T03:14:44.8499004Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-9F3xBI/rebno.db
2026-05-16T03:14:44.8500674Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T03:14:44.8501833Z apps/server test: [run-migrations] OK
2026-05-16T03:14:44.8517960Z apps/server test:  [32m✓[39m test/run-migrations.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 52[2mms[22m[39m
2026-05-16T03:14:45.1373805Z apps/server test:  [32m✓[39m test/log.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 22[2mms[22m[39m
2026-05-16T03:14:45.2118838Z apps/client test:  [32m✓[39m src/__test__/nameplate-stability.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 23[2mms[22m[39m
2026-05-16T03:14:45.3858197Z apps/server test:  [32m✓[39m test/admin-stubs.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T03:14:45.6919615Z apps/server test:  [32m✓[39m test/legacy-login.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 20[2mms[22m[39m
2026-05-16T03:14:45.9185650Z apps/server test:  [32m✓[39m test/health.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T03:14:46.4145656Z apps/client test:  [32m✓[39m src/__test__/nameplate.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 116[2mms[22m[39m
2026-05-16T03:14:46.6985034Z apps/server test: [90mstdout[2m | test/tick-accumulator.test.ts
2026-05-16T03:14:46.7004640Z apps/server test: [22m[39m◇ injected env (50) from ../../../../../../../etc/environment // tip: ⌘ suppress logs { quiet: true }
2026-05-16T03:14:46.7084456Z apps/server test: ℹ️  optional .env file not found: .env.test, .env
2026-05-16T03:14:47.4585761Z apps/server test:  [32m✓[39m test/tick-accumulator.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T03:14:47.4652784Z apps/server test: [2m Test Files [22m [1m[32m12 passed[39m[22m[90m (12)[39m
2026-05-16T03:14:47.4674259Z apps/server test: [2m      Tests [22m [1m[32m70 passed[39m[22m[90m (70)[39m
2026-05-16T03:14:47.4686335Z apps/server test: [2m   Start at [22m 03:14:40
2026-05-16T03:14:47.4702913Z apps/server test: [2m   Duration [22m 6.82s[2m (transform 577ms, setup 0ms, import 3.32s, tests 1.04s, environment 2ms)[22m
2026-05-16T03:14:47.5043537Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.test.ts [2m([22m[2m29 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T03:14:47.5117851Z apps/server test: Done
2026-05-16T03:14:48.1885216Z apps/client test:  [32m✓[39m src/__test__/login-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T03:14:48.9308156Z apps/client test:  [32m✓[39m src/__test__/colyseus-client.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T03:14:49.6161662Z apps/client test:  [32m✓[39m src/__test__/player-renderer.teleport.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-16T03:14:50.3196527Z apps/client test:  [32m✓[39m src/__test__/player-renderer-spawn-delay.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 19[2mms[22m[39m
2026-05-16T03:14:51.0189430Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T03:14:51.7494753Z apps/client test:  [32m✓[39m src/__test__/reconnect.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 74[2mms[22m[39m
2026-05-16T03:14:52.4990191Z apps/client test:  [32m✓[39m src/__test__/chat-hud.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 83[2mms[22m[39m
2026-05-16T03:14:53.1820663Z apps/client test:  [32m✓[39m src/__test__/nameplate-color.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 32[2mms[22m[39m
2026-05-16T03:14:53.8605588Z apps/client test:  [32m✓[39m src/__test__/reconciler.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T03:14:54.5286322Z apps/client test:  [32m✓[39m src/__test__/room-renderer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:14:55.2659640Z apps/client test:  [32m✓[39m src/__test__/force-reset-overlay.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 72[2mms[22m[39m
2026-05-16T03:14:55.9947006Z apps/client test:  [32m✓[39m src/__test__/esc-menu.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 79[2mms[22m[39m
2026-05-16T03:14:56.6540627Z apps/client test:  [32m✓[39m src/__test__/prediction.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:14:57.3817828Z apps/client test:  [32m✓[39m src/__test__/background-renderer.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 72[2mms[22m[39m
2026-05-16T03:14:58.0538227Z apps/client test:  [32m✓[39m src/__test__/extrapolation.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:14:58.7346747Z apps/client test:  [32m✓[39m src/__test__/sprite-state-rate.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T03:14:59.4225781Z apps/client test:  [32m✓[39m src/__test__/room-layout-verify.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T03:15:00.0985390Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher-shift.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T03:15:00.7902164Z apps/client test:  [32m✓[39m src/__test__/boot-font-gate.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T03:15:01.4826357Z apps/client test:  [32m✓[39m src/__test__/auth-client.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T03:15:02.1385443Z apps/client test:  [32m✓[39m src/__test__/room-collision-bottom-edge.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T03:15:02.8021378Z apps/client test:  [32m✓[39m src/__test__/depth-set.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 3[2mms[22m[39m
2026-05-16T03:15:03.4646128Z apps/client test:  [32m✓[39m src/__test__/legacy-origin.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T03:15:04.1322916Z apps/client test:  [32m✓[39m src/__test__/atlas-loader.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T03:15:04.8049246Z apps/client test:  [32m✓[39m src/__test__/protocol-version-check.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T03:15:05.4645080Z apps/client test:  [32m✓[39m src/__test__/env.test.ts [2m([22m[2m5 tests[22m[2m | [22m[33m4 skipped[39m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T03:15:05.4865243Z apps/client test: [2m Test Files [22m [1m[32m31 passed[39m[22m[90m (31)[39m
2026-05-16T03:15:05.4884734Z apps/client test: [2m      Tests [22m [1m[32m213 passed[39m[22m[2m | [22m[90m4 todo[39m[90m (217)[39m
2026-05-16T03:15:05.4891384Z apps/client test: [2m   Start at [22m 03:14:40
2026-05-16T03:15:05.4894515Z apps/client test: [2m   Duration [22m 24.79s[2m (transform 917ms, setup 66ms, collect 1.60s, tests 1.07s, environment 14.46s, prepare 2.72s)[22m
2026-05-16T03:15:05.6220748Z apps/client test: Done
2026-05-16T03:15:05.6312963Z 
2026-05-16T03:15:05.6314245Z verify-phase-4: OK (12 steps green)
